package com.ruoyi.system.service.impl.wechat;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.constant.wechat.WechatConstants;
import com.ruoyi.common.core.domain.entity.wechat.WechatArea;
import com.ruoyi.common.core.domain.entity.wechat.WechatCity;
import com.ruoyi.common.core.domain.entity.wechat.WechatProvince;
import com.ruoyi.common.core.domain.entity.wechat.WechatStreet;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.system.mapper.wechat.WechatAreaMapper;
import com.ruoyi.system.mapper.wechat.WechatCityMapper;
import com.ruoyi.system.mapper.wechat.WechatProvinceMapper;
import com.ruoyi.system.mapper.wechat.WechatStreetMapper;
import com.ruoyi.system.service.wechat.IWechatAdministrativeUnitService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 微信小程序行政单位
 *
 * @author jiexiang.sun/Jason
 * @version 1.0.0
 * @create 2022-03-04 0:07
 **/
@Service
@Slf4j
public class WechatAdministrativeUnitServiceImpl implements IWechatAdministrativeUnitService {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private WechatProvinceMapper wechatProvinceMapper;

    @Autowired
    private WechatCityMapper wechatCityMapper;

    @Autowired
    private WechatAreaMapper wechatAreaMapper;

    @Autowired
    private WechatStreetMapper wechatStreetMapper;

    /**
     * 缓存行政单位相关信息
     */
    @Override
    public void loadAdministrativeUnitCache() {
        //清空缓存
        cleanCache();
        //初始化信息到缓存
        loadingCache();
    }

    /**
     * 将省市区信息装载到缓存
     */
    private void loadingCache() {
        LambdaQueryWrapper<WechatProvince> provinceQW = new LambdaQueryWrapper<>();
        provinceQW.orderByAsc(WechatProvince::getCode);
        List<WechatProvince> wechatProvinces = wechatProvinceMapper.selectList(provinceQW);

        LambdaQueryWrapper<WechatCity> cityQW = new LambdaQueryWrapper<>();
        cityQW.orderByAsc(WechatCity::getCode);
        List<WechatCity> wechatCities = wechatCityMapper.selectList(cityQW);

        LambdaQueryWrapper<WechatArea> areaQW = new LambdaQueryWrapper<>();
        areaQW.orderByAsc(WechatArea::getCode);
        List<WechatArea> wechatAreas = wechatAreaMapper.selectList(areaQW);

        LambdaQueryWrapper<WechatStreet> streetQW = new LambdaQueryWrapper<>();
        streetQW.orderByAsc(WechatStreet::getCode);
        List<WechatStreet> wechatStreets = wechatStreetMapper.selectList(streetQW);

        if (CollectionUtil.isNotEmpty(wechatProvinces)) {
            redisCache.setCacheList(WechatConstants.WECHAT_PROVINCE_CACHE_KEY, wechatProvinces);

            if (CollectionUtil.isNotEmpty(wechatCities)) {
                wechatProvinces.forEach(p -> {
                    List<WechatCity> citys = new ArrayList<>();
                    wechatCities.forEach(c -> {
                        if (p.getCode().equals(c.getProvinceCode())) {
                            citys.add(c);

                            if (CollectionUtil.isNotEmpty(wechatAreas)) {
                                List<WechatArea> areas = new ArrayList<>();
                                wechatAreas.forEach(a -> {
                                    if (c.getCode().equals(a.getCityCode())) {
                                        areas.add(a);

                                        if (CollectionUtil.isNotEmpty(wechatStreets)) {
                                            List<WechatStreet> streets = new ArrayList<>();
                                            wechatStreets.forEach(s -> {
                                                if (a.getCode().equals(s.getAreaCode())) {
                                                    streets.add(s);
                                                }
                                            });

                                            redisCache.setCacheList(WechatConstants.WECHAT_STREET_CACHE_KEY_PREFIX + p.getCode() + ":" + c.getCode() + ":" + a.getCode(), streets);
                                        }
                                    }
                                });

                                redisCache.setCacheList(WechatConstants.WECHAT_AREA_CACHE_KEY_PREFIX + p.getCode() + ":" + c.getCode(), areas);
                            }
                        }
                    });
                    redisCache.setCacheList(WechatConstants.WECHAT_CITY_CACHE_KEY_PREFIX + p.getCode(), citys);
                });
            }
        }
    }

    @Override
    public List<WechatProvince> getProvince() {
        return redisCache.getCacheList(WechatConstants.WECHAT_PROVINCE_CACHE_KEY);
    }

    @Override
    public List<WechatCity> getCitys(Integer provinceCode) {
        String key;

        if (null == provinceCode) {
            key = WechatConstants.WECHAT_CITY_CACHE_KEY_PREFIX + "*";
        } else {
            key = WechatConstants.WECHAT_CITY_CACHE_KEY_PREFIX + provinceCode;
        }

        Collection<String> keys = redisCache.keys(key);
        List<WechatCity> result = new ArrayList<>();
        keys.forEach(k -> {
            result.addAll(redisCache.getCacheList(k));
        });
        return result;
    }

    @Override
    public List<WechatArea> getAreas(Integer cityCode) {
        String key;

        if (null == cityCode) {
            key = WechatConstants.WECHAT_AREA_CACHE_KEY_PREFIX + "*:*";
        } else {
            key = WechatConstants.WECHAT_AREA_CACHE_KEY_PREFIX + "*:" + cityCode;
        }

        Collection<String> keys = redisCache.keys(key);
        List<WechatArea> result = new ArrayList<>();
        keys.forEach(k -> {
            result.addAll(redisCache.getCacheList(k));
        });
        return result;
    }

    @Override
    public List<WechatStreet> getStreets(Integer areaCode) {
        String key;

        if (null == areaCode) {
            key = WechatConstants.WECHAT_STREET_CACHE_KEY_PREFIX + "*:*";
        } else {
            key = WechatConstants.WECHAT_STREET_CACHE_KEY_PREFIX + "*:" + areaCode;
        }

        Collection<String> keys = redisCache.keys(key);
        List<WechatStreet> result = new ArrayList<>();
        keys.forEach(k -> {
            result.addAll(redisCache.getCacheList(k));
        });
        return result;
    }

    /**
     * 删除行政单位缓存
     */
    private void cleanCache() {
        redisCache.deleteObject(WechatConstants.WECHAT_PROVINCE_CACHE_KEY);
        Collection<String> keys = redisCache.keys(WechatConstants.WECHAT_AREA_CACHE_KEY_PREFIX + "*");
        redisCache.deleteObject(keys);
        keys = redisCache.keys(WechatConstants.WECHAT_CITY_CACHE_KEY_PREFIX + "*");
        redisCache.deleteObject(keys);
    }

}
